﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;

namespace SpaceArcade
{
    class Game
    {        
        System.Windows.Forms.Timer gameTimer;
        public int Score;
        int PrevScene;
        private bool isPaused = false;
        public static int currentGameLevel;

        public Form GameForm
        {
            get;
            private set;
        }

        public List<Scene> Scenes
        {
            get;
            private set;
        }

        public int CurrentScene
        {
            get;
            private set;
        }



        public delegate void PauseHendler();
        public event PauseHendler OnPause;

        
        public Game(Form1 gameForm)
        {
            Scenes = new List<Scene>();
            this.gameTimer = new System.Windows.Forms.Timer();
            this.gameTimer.Interval = 20;
            this.gameTimer.Tick += Draw;
            this.gameTimer.Tick += Update;
            this.GameForm = gameForm;
            this.GameForm.KeyDown += OnKeyDown;
            this.GameForm.KeyUp += OnKeyUp;
            this.GameForm.MouseUp += menuClick;
            this.GameForm.MouseMove += OnMove;
            OnPause += Paused;

            GameScene.OnFall += AddScore;           
            GameScene.OnSave += SaveResult;
           
            
            
            Menu menu = new Menu(GameForm);
            RatingTable rating = new RatingTable(GameForm);
            Scenes.Add(menu);
            Scenes.Add(rating);
            Scenes.Add(new GameScene(new Background("Background4.png", GameForm.Width, GameForm.Height), GameForm));
            Scenes.Add(new Level2(new Background("Background1.png", GameForm.Width, GameForm.Height), GameForm));
            Scenes.Add(new Level3(new Background("Background2.png", GameForm.Width, GameForm.Height), GameForm));

            
            SetCurrentScene(0);

           
        }

        public void AddScore()
        {
            if (this.Scenes[CurrentScene] is GameScene)
            {    
                if (((GameScene)this.Scenes[CurrentScene]).myplayer.HitPoints > 0)
                Score++;
            }
        }


        protected void Paused()
        {            
            GameForm.CreateGraphics().DrawString(String.Format("PAUSED"), new Font("Arial", 56, FontStyle.Bold), Brushes.White, new Point(GameForm.Width / 2 - 170, GameForm.Height / 2 - 60));
        }

        
        public void SaveResult()
        {
            SaveResultForm SaveForm = new SaveResultForm(Score);
            SaveForm.Show();              
        }

        public void OnMove(object sender, MouseEventArgs e)
        {
            if (this.Scenes[CurrentScene] is Menu)
            {
                ((Menu)this.Scenes[CurrentScene]).OnMove(sender, e);
            }
        }
        
        public void menuClick(object sender, MouseEventArgs e)
        {
            if (this.Scenes[CurrentScene] is Menu)
            {
                ((Menu)this.Scenes[CurrentScene]).OnClick(sender, e);
                if (!((Menu)this.Scenes[CurrentScene]).activeSaving)
                {
                    switch (((Menu)this.Scenes[CurrentScene]).CurrentItem)
                    {
                        case 0:
                            SetCurrentScene(2);
                            break;
                        case 1:
                            LoadGame();
                            break;
                        case 2:
                            SetCurrentScene(1);
                            break;
                        case 3:
                            Application.Exit();
                            break;
                    }
                }else
                {
                    switch (((Menu)this.Scenes[CurrentScene]).CurrentItem)
                    {
                        case 0:
                            SetCurrentScene(2);
                            break;
                        case 1:
                            LoadGame();
                        break;
                        case 2:
                            SaveGame();
                            break;
                        case 3:
                            SetCurrentScene(1);
                            break;
                        case 4:
                            Application.Exit();
                            break;
                    }
                }
            }
        }

        
        
        private void SaveGame()
        {            
            SaveFileDialog sf = new SaveFileDialog();
            sf.Filter = "Save files (*.save)|*.save";
            sf.InitialDirectory = GamePath.SavesPath;
           
            if (sf.ShowDialog() == DialogResult.OK)
            {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(sf.FileName))
                {
                    if (Scenes[PrevScene] is GameScene)
                    {
                        sw.WriteLine(string.Format(Convert.ToString(((GameScene)Scenes[PrevScene]).myplayer.HitPoints)+ ";" + Convert.ToString(Score)
                          + ";"  + Convert.ToString(PrevScene)));
                    }
                }
            }
        }

        private void LoadGame()
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Filter = "Save files (*.save)|*.save";
            op.InitialDirectory = GamePath.SavesPath;
            int HP = 3;
            int Scenenumber = 2;
            int StartingScore = 0;         

            if (op.ShowDialog() == DialogResult.OK)
            {
                using (System.IO.StreamReader sr = new System.IO.StreamReader(op.FileName))
                {
                    string[] lines;
                    lines = sr.ReadLine().Split(';');
                    HP = Convert.ToInt32(lines[0]);
                    StartingScore = Convert.ToInt32(lines[1]);
                    Scenenumber = Convert.ToInt32(lines[2]);
                   
                }
                ((GameScene)this.Scenes[Scenenumber]).myplayer.HitPoints = HP;
               
                Score = StartingScore;
                SetCurrentScene(Scenenumber);
            }
            
        }

        public void AddScene(Scene sceneToAdd)
        {
            sceneToAdd.GameForm = this.GameForm;
            this.Scenes.Add(sceneToAdd);
        }       
        
        public void SetCurrentScene(int index)
        {
            Stop();
            
                this.Scenes[this.CurrentScene].IsActive = false;
                this.Scenes[index].IsActive = true;
                this.CurrentScene = index;                
            
                switch(this.CurrentScene)
                {
                    case 2:
                        currentGameLevel = 1;
                        break;
                    case 3:
                        currentGameLevel = 2;
                        break;
                    case 4:
                        currentGameLevel = 3;
                        break;
                }            
            Run();
        }

        public void Run()
        {            
            this.gameTimer.Start();
        }

        public void Stop()
        {            
            this.gameTimer.Stop();
        }

        public void Pause()
        {
            if (OnPause != null)
                OnPause();
            gameTimer.Stop();
            isPaused = true;
           
        }

        public void Unpause()
        {
            gameTimer.Start();
            isPaused = false;
        }

        protected void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (this.Scenes[this.CurrentScene] is GameScene)
            {
                ((GameScene)this.Scenes[this.CurrentScene]).OnKeyDown(e);
                if (e.KeyCode == Keys.P)
                {
                    if (!isPaused)
                        this.Pause();
                    else
                        this.Unpause();
                }
            }
            
        }

        
        protected void OnKeyUp(object sender, KeyEventArgs e)
        {

            if (this.Scenes[this.CurrentScene] is GameScene)
            {
                ((GameScene)this.Scenes[this.CurrentScene]).OnKeyUp(e);
            }

            if (e.KeyCode == Keys.Escape)
            {
                if (CurrentScene != 1)
                {
                    if (Score > 0)
                    {                       
                        ((Menu)this.Scenes[0]).activeSaving = true;
                        
                    }
                    PrevScene = CurrentScene;
                }else
                {
                    ((Menu)this.Scenes[0]).activeSaving = false;
                }
                SetCurrentScene(0);                
            }
        }

        protected void Update(object sender, EventArgs e)
        {
            if (this.Scenes[this.CurrentScene] is GameScene)
            {
                ((GameScene)this.Scenes[this.CurrentScene]).Update(e, gameTimer);
            }

            switch(CurrentScene)
            {
                case 2:
                    if (Score > 250)
                    {
                        Stop();
                        
                        SetCurrentScene(CurrentScene + 1);
                       
                        ((GameScene)Scenes[CurrentScene]).myplayer = ((GameScene)Scenes[CurrentScene - 1]).myplayer;
                        Run();
                    }
                    break;
                case 3:
                    if (Score > 500)
                    {
                        Stop();
                        SetCurrentScene(CurrentScene + 1);
                        ((GameScene)Scenes[CurrentScene]).myplayer = ((GameScene)Scenes[CurrentScene - 1]).myplayer;
                        Run();
                    }
                    break;
            }           
            
        }
        protected void Draw(object sender, EventArgs e)
        {
           
            this.Scenes[this.CurrentScene].Draw();
            if (this.Scenes[this.CurrentScene] is GameScene)
            {
                Graphics.FromImage(this.Scenes[this.CurrentScene].gameBM).DrawString(String.Format("Score:{0}", Score), new Font("Cooper black", 30, FontStyle.Bold), Brushes.White, new Point(20, 30));
            }           
            this.GameForm.CreateGraphics().DrawImage(this.Scenes[this.CurrentScene].gameBM, 0, 0);
        }
    }  
}
